/*
 * Copyright (c) 2023, Nordic Semiconductor
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be
 * used to endorse or promote products derived from this software without specific prior
 * written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

@file:Suppress("unused")

package no.nordicsemi.android.common.permissions.ble

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import no.nordicsemi.android.common.permissions.ble.util.BlePermissionState
import no.nordicsemi.android.common.permissions.ble.view.LocationPermissionRequiredView
import no.nordicsemi.android.common.permissions.ble.viewmodel.PermissionViewModel

/**
 * A wrapper for composables that require Location.
 *
 * Location is required for Bluetooth LE scanning from Android 6 Marshmallow.
 * Starting from Android 12 location may not be required if `BLUETOOTH_SCAN` permission was
 * requested with `neverForLocation` flag.
 *
 * This composable will display a view based on the state of the location.
 *
 * ### Example:
 * ```kotlin
 * RequireBluetooth(
 *     onChanged = { onScanningStateChanged(it) }
 * ) {
 *     RequireLocation(
 *         onChanged = { onScanningStateChanged(it) }
 *     ) {
 *         // Bluetooth scanner views
 *     }
 * }
 * ```
 *
 * @param onChanged A callback that will be called when the state of the location changes.
 * @param contentWithoutLocation A composable that will be displayed when location is not available.
 * @param content A composable that will be displayed when location is available.
 */
@Composable
fun RequireLocation(
    onChanged: (Boolean) -> Unit = {},
    contentWithoutLocation: @Composable () -> Unit = { LocationPermissionRequiredView() },
    content: @Composable (isLocationRequiredAndDisabled: Boolean) -> Unit,
) {
    val viewModel = hiltViewModel<PermissionViewModel>()
    val state by viewModel.locationPermission.collectAsStateWithLifecycle()

    LaunchedEffect(state) {
        onChanged(state is BlePermissionState.Available || (state as BlePermissionState.NotAvailable).reason == BlePermissionNotAvailableReason.DISABLED)
    }

    when (val s = state) {
        is BlePermissionState.NotAvailable -> when (s.reason) {
            BlePermissionNotAvailableReason.DISABLED -> content(true)
            else -> contentWithoutLocation()
        }

        BlePermissionState.Available -> content(false)
    }
}